#include "Action_Guard.h"

const char* Action_Guard::STR = "Guard";

Action_Guard::Action_Guard(void) : ActionChecker(1, true)
{
	Functions[0] = bind(&Action_Guard::Pattern, this, placeholders::_1);
	Interval_frame[0] = 30;

	_actionInfo.ActionType = EAction_Guard;
	_actionInfo.soundType = SOUND_TYPE_GUARD_SUCCESS;
	_actionInfo.removable = false;
	_actionInfo.enabled = false;
}


Action_Guard::~Action_Guard(void)
{
}

void Action_Guard::SetActionInfo(const JointInfo& joint, XnUInt32 userID, bool ifChange) {
	XnPoint3D pH_R = joint[XN_SKEL_RIGHT_HAND].position;
	XnPoint3D pH_L = joint[XN_SKEL_LEFT_HAND].position;

	_actionInfo.userID = userID;
	_actionInfo.start = pH_L;
	_actionInfo.direction = Math::GetVector3D_P(pH_L, pH_R);
	
	if (!ifChange && !_actionInfo.enabled) {
		//_actionInfo.magnitude = (float)_energy;
		//_energy = 10;
		_actionInfo.enabled = true;
		_actionInfo.effect = NULL;
	}
}

ActionInfo* Action_Guard::GetActionInfo() {
	return &_actionInfo;
}

const char* Action_Guard::GetActionStr() const {
	return Action_Guard::STR;
}

//---------

bool Action_Guard::Pattern(const JointInfo& joint) {
	XnPoint3D pH_R = joint[XN_SKEL_RIGHT_HAND].position;
	XnPoint3D pH_L = joint[XN_SKEL_LEFT_HAND].position;
	XnPoint3D pE_R = joint[XN_SKEL_RIGHT_ELBOW].position;
	XnPoint3D pE_L = joint[XN_SKEL_LEFT_ELBOW].position;
	XnPoint3D pS_R = joint[XN_SKEL_RIGHT_SHOULDER].position;
	XnPoint3D pS_L = joint[XN_SKEL_LEFT_SHOULDER].position;

	XnVector3D v1_R = Math::GetVector3D_P(pE_R, pH_R);
	XnVector3D v1_L = Math::GetVector3D_P(pE_L, pH_L);
	XnVector3D v2_R = Math::GetVector3D_P(pE_R, pS_R);
	XnVector3D v2_L = Math::GetVector3D_P(pE_L, pS_L);

	float fd1 = Math::Vec3_ThetaDegree(v1_R, v1_L); // 
	float fd2 = Math::Vec3_ThetaDegree(v2_R, v2_L); // 

	//std::cout << "fd1:" << fd1 << '\n' << "fd2:" << fd2 << endl;

	if (fd1 > 50.0f || fd2 > 50.0f) { this->EraceGuard(); return false; }

	float fp_R = Math::Vec3_ThetaDegree(v1_R, v2_R);
	float fp_L = Math::Vec3_ThetaDegree(v1_L, v2_L);

	//std::cout << "fpR:" << fp_R << '\n' << "fpL:" << fp_L << endl;

	if (abs(fp_R - 90.0f) > 20.0f || abs(fp_L - 90.0f) > 20.0f) { this->EraceGuard(); return false; }

	if (_actionInfo.enabled) {
		this->SetActionInfo(joint, _actionInfo.userID, true); 
		if (_actionInfo.effect != NULL) {
			_actionInfo.effect->renewStartPoint(_actionInfo.start);
			_actionInfo.effect->renewDirection(_actionInfo.direction);
		}
		if (this->NowFrame() % 3 == 0) {
			SoundController::Play_Sound(SOUND_TYPE_GUARD_GUARDING);
		}
		return false;
	}
	return true;
}

void Action_Guard::EraceGuard() {
	if (_actionInfo.effect != NULL) {
		_actionInfo.enabled = false;
	}
}

bool Action_Guard::IsActionExcluding() {
	return _actionInfo.enabled;
}

void Action_Guard::OnResetAction() {
	this->EraceGuard();
}